package com.yusheng.tr.common.core.service;

import com.yusheng.constant.CacheConstants;
import com.yusheng.constant.Constants;
import com.yusheng.exceptions.ServiceException;
import com.yusheng.service.RedisService;
import com.yusheng.tr.common.core.context.AuthenticationContextHolder;
import com.yusheng.tr.common.core.entity.system.SysUser;
import com.yusheng.tr.common.core.manager.AsyncManager;
import com.yusheng.tr.common.core.manager.factory.AsyncFactory;
import com.yusheng.tr.common.core.utils.SecurityUtils;
import com.yusheng.utils.MessageUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.core.Authentication;
import org.springframework.stereotype.Component;

import java.util.concurrent.TimeUnit;

/**
 * 登录密码方法
 */
@Component
public class SysPasswordService {

    @Autowired
    private RedisService redisCache;

    @Value(value = "${user.password.maxRetryCount}")
    private int maxRetryCount;

    @Value(value = "${user.password.lockTime}")
    private Long lockTime;

    /**
     * 登录账户密码错误次数缓存键名
     *
     * @param username 用户名
     * @return 缓存键key
     */
    private String getCacheKey(String username) {
        return CacheConstants.PWD_ERR_CNT_KEY + username;
    }

    public void validate(SysUser user) {
        Authentication usernamePasswordAuthenticationToken = AuthenticationContextHolder.getContext();
        String nameAndType = usernamePasswordAuthenticationToken.getName();
        String userType = nameAndType.split(",")[1];
        String password = usernamePasswordAuthenticationToken.getCredentials().toString();
        if (userType.equals("pc")){
            Integer retryCount = redisCache.getCacheObject(getCacheKey(nameAndType));
            if (retryCount == null) {
                retryCount = 0;
            }
            if (retryCount >= maxRetryCount) {
                AsyncManager.me().execute(AsyncFactory.recordLogininfor(nameAndType, Constants.LOGIN_FAIL,
                        MessageUtils.message("user.password.retry.limit.exceed", maxRetryCount, lockTime)));
                throw new ServiceException("输入密码错误已达" + maxRetryCount + "次，" + "请稍等" + lockTime + "分钟");
            }
            if (matches(user, password)) {
                retryCount = retryCount + 1;
                AsyncManager.me().execute(AsyncFactory.recordLogininfor(nameAndType, Constants.LOGIN_FAIL,
                        MessageUtils.message("user.password.retry.limit.count", retryCount)));
                redisCache.setCacheObject(getCacheKey(nameAndType), retryCount, lockTime, TimeUnit.MINUTES);
                throw new ServiceException("密码输入错误，请核对后重试！");
            } else {
                clearLoginRecordCache(nameAndType);
            }
        }else {
            if (matches(user, password)){
                throw new ServiceException("验证码输入错误，请核对后重试！");
            }
        }

    }

    public boolean matches(SysUser user, String rawPassword) {
        return !SecurityUtils.matchesPassword(rawPassword, user.getPassword());
    }

    public void clearLoginRecordCache(String loginName) {
        if (redisCache.hasKey(getCacheKey(loginName))) {
            redisCache.deleteObject(getCacheKey(loginName));
        }
    }
}
